/*
 * @Author: LVGRAPE
 * @LastEditors: LVGRAPE
 */
#include "flash.h"
#include "IAP.h"
#include "USART_Configuration.h"
#include "delay.h"

// #define IAP_DEBUG , NOTE DEBUG时会引入printf函数， 代码体积会激增，要么链接文件里的内存大小才能用

/**
  * @brief  Easing app flash sector, form APP_START_ADDR to the end(64KB)
  * @retval operate
			success: 0.
			fail: 1;
  * @note   This function must be used only when the Flash operate enable.
  */
u8 Flash_AppSector_Erase()
{
	FLASH_Status status;
	FLASH_Unlock();
	for (uint32_t i = APP_START_ADDR; i < (0x08000000 + APP_FLASH_SIZE); i += 2048)
	{
		status = FLASH_ErasePage(i);
#ifdef IAP_DEBUG
		printf("\nerasing page: 0x%lx\n", i);
#endif // IAP_DEBUG
		while (FLASH_GetBank1Status() != FLASH_PRC_DONE);
		if (status != FLASH_PRC_DONE)
			return 1;
	}
	return 0;
}
/**
  * @brief  wite N bytes data to flash
  * @arg WriteAddr: flash addr, this vale must between APP_START_ADDR and Flash total size
  * @arg * pBuffer: point to data
  * @arg size: data size
  * @note   This function must be used only when the Flash operate enable.
  */
FLASH_Status Flash_write_16bits(u32 WriteAddr, u8* pBuffer, u16 size)
{
	u32 addr = WriteAddr;
	FLASH_Status status;
	for (u16 i = 0; i < size; i += 2)
	{
		// u16 halfword = (((u16)(pBuffer[i + 1])) << 8) + pBuffer[i];
		// status = FLASH_ProgramHalfWord(addr, halfword);
		status = FLASH_ProgramHalfWord(addr, *(uint32_t *)(pBuffer+i));
		// status = FLASH_ProgramWord(addr, *(uint32_t *)(pBuffer+i));

#ifdef IAP_DEBU
		if (status == FLASH_COMPLETE)
		{
			printf("Program:%d at address 0x%lx\n", halfword, addr);
		}
#endif // IAP_DEBU
		if (status != FLASH_PRC_DONE)
		{
			return status;
		}
		addr += 2;
	}
	return status;
}
void Flash_Read(u32 ReadAddr, u8* pBuffer, u16 size)
{
	for (u16 i = 0; i < size; i++)
	{
		*pBuffer = *(__IO uint8_t*)ReadAddr;
		pBuffer++;
		ReadAddr++;
	}
}
void FLASH_RW_TEST()
{
	const uint8_t testBuffer[12]={1,2,3,4,5,6,7,8,9,10,11,12};
	uint8_t readBuffer[12];
	uint8_t str[2];
	uint32_t tPr=0,tpr0;
	FLASH_Unlock();
	tPr = systick_cnt_ms;
	tpr0 = tPr;
	rt_kprintf(">>>%d ms\n",tPr);
	for (uint8_t i = 0; i < 125; i++)
	{
		tPr = systick_cnt_ms;
		FLASH_ErasePage((APP_START_ADDR + (i*2048)));

		rt_kprintf("^%d ms\n",(systick_cnt_ms - tPr));
	}

	// FLASH_ErasePage(APP_START_ADDR);
	// FLASH_ErasePage(APP_START_ADDR+204);
	// FLASH_ErasePage(APP_START_ADDR);
	// FLASH_ErasePage(APP_START_ADDR);
	// FLASH_ErasePage(APP_START_ADDR);
	// FLASH_ErasePage(APP_START_ADDR);
	// FLASH_ErasePage(APP_START_ADDR);
	rt_kprintf("<<<%d ms\n",(systick_cnt_ms - tpr0));
	for(uint8_t i=0;i<12;i++)
	{
		FLASH_ProgramByte(APP_START_ADDR+i,testBuffer[i]);
	}
	Flash_Read(APP_START_ADDR,readBuffer,12);
	for(uint8_t i=0;i<12;i++)
	{
		usart_sendBytes((uint8_t*)myitoa(readBuffer[i],(char*)str,10));
		usart_sendByte('\n');
	}
	FLASH_Lock();
}
